Skip to content

Add Page.captureScreenshot CDP support (#56307)#56307

Closed
huntie wants to merge 1 commit intofacebook:mainfrom
huntie:export-D99099930
Closed

Add Page.captureScreenshot CDP support (#56307)#56307
huntie wants to merge 1 commit intofacebook:mainfrom
huntie:export-D99099930

Conversation

@huntie
Copy link
Copy Markdown
Member

@huntie huntie commented Apr 1, 2026

Summary:

Implement the Page.captureScreenshot CDP command in the inspector backend, allowing DevTools to capture an on-demand screenshot of the current app view. This is a minimal implementation supporting only the format (jpeg/png/webp) and quality (0-100, jpeg only) parameters, returning base64-encoded image data.

The feature is gated behind a new fuseboxCaptureScreenshotEnabled React Native feature flag, wired through InspectorFlags following the same pattern as frame recording.

Motivation

Improve agent verification / user feedback during AI sessions. We've proven that screenshots (in performance traces) are useful for understanding how components render on screen, and exposing this as an on-demand CDP method is relatively cheap today vs the larger task of modelling the DOM (Elements panel).

Changes

  • New fuseboxCaptureScreenshotEnabled feature flag + InspectorFlags wiring (C++, Android JNI, Kotlin)
  • HostTargetDelegate::captureScreenshot() virtual method with async callback
  • C++ CDP handler in HostAgent — parses format/quality, delegates to platform, sends async CDP response (gated by flag)
  • iOS (RCTHost.mm): Captures key window via UIGraphicsImageRenderer + drawViewHierarchyInRect, encodes to PNG/JPEG
  • Android (ReactHostImpl.kt): Captures decor view via Bitmap + Canvas + View.draw(), encodes to PNG/JPEG/WebP
  • 4 C++ tests: success, failure, param forwarding, flag-disabled rejection

Changelog: [Internal]

Reviewed By: hoxyq

Differential Revision: D99099930

@meta-cla meta-cla bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Apr 1, 2026
@facebook-github-tools facebook-github-tools bot added p: Facebook Partner: Facebook Partner labels Apr 1, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync bot commented Apr 1, 2026

@huntie has exported this pull request. If you are a Meta employee, you can view the originating Diff in D99099930.

@huntie huntie force-pushed the export-D99099930 branch from ee8456d to 9ac5354 Compare April 7, 2026 18:08
@meta-codesync meta-codesync bot changed the title Add Page.captureScreenshot CDP support Add Page.captureScreenshot CDP support (#56307) Apr 7, 2026
huntie added a commit to huntie/react-native that referenced this pull request Apr 7, 2026
Summary:
Pull Request resolved: facebook#56307

Implement the `Page.captureScreenshot` CDP command in the inspector backend, allowing DevTools to capture an on-demand screenshot of the current app view. This is a minimal implementation supporting only the `format` (jpeg/png/webp) and `quality` (0-100, jpeg only) parameters, returning base64-encoded image data.

The feature is gated behind a new `fuseboxCaptureScreenshotEnabled` React Native feature flag, wired through `InspectorFlags` following the same pattern as frame recording.

**Motivation**

Improve agent verification / user feedback during AI sessions. We've proven that screenshots (in performance traces) are useful for understanding how components render on screen, and exposing this as an on-demand CDP method is relatively cheap today vs the larger task of modelling the DOM (Elements panel).

**Changes**

- New `fuseboxCaptureScreenshotEnabled` feature flag + `InspectorFlags` wiring (C++, Android JNI, Kotlin)
- `HostTargetDelegate::captureScreenshot()` virtual method with async callback
- C++ CDP handler in `HostAgent` — parses `format`/`quality`, delegates to platform, sends async CDP response (gated by flag)
- iOS (`RCTHost.mm`): Captures key window via `UIGraphicsImageRenderer` + `drawViewHierarchyInRect`, encodes to PNG/JPEG
- Android (`ReactHostImpl.kt`): Captures decor view via `Bitmap` + `Canvas` + `View.draw()`, encodes to PNG/JPEG/WebP
- 4 C++ tests: success, failure, param forwarding, flag-disabled rejection

Changelog: [Internal]

Differential Revision: D99099930
Summary:
Pull Request resolved: facebook#56307

Implement the `Page.captureScreenshot` CDP command in the inspector backend, allowing DevTools to capture an on-demand screenshot of the current app view. This is a minimal implementation supporting only the `format` (jpeg/png/webp) and `quality` (0-100, jpeg only) parameters, returning base64-encoded image data.

The feature is gated behind a new `fuseboxCaptureScreenshotEnabled` React Native feature flag, wired through `InspectorFlags` following the same pattern as frame recording.

**Motivation**

Improve agent verification / user feedback during AI sessions. We've proven that screenshots (in performance traces) are useful for understanding how components render on screen, and exposing this as an on-demand CDP method is relatively cheap today vs the larger task of modelling the DOM (Elements panel).

**Changes**

- New `fuseboxCaptureScreenshotEnabled` feature flag + `InspectorFlags` wiring (C++, Android JNI, Kotlin)
- `HostTargetDelegate::captureScreenshot()` virtual method with async callback
- C++ CDP handler in `HostAgent` — parses `format`/`quality`, delegates to platform, sends async CDP response (gated by flag)
- iOS (`RCTHost.mm`): Captures key window via `UIGraphicsImageRenderer` + `drawViewHierarchyInRect`, encodes to PNG/JPEG
- Android (`ReactHostImpl.kt`): Captures decor view via `Bitmap` + `Canvas` + `View.draw()`, encodes to PNG/JPEG/WebP
- 4 C++ tests: success, failure, param forwarding, flag-disabled rejection

Changelog: [Internal]

Reviewed By: hoxyq

Differential Revision: D99099930
@huntie huntie force-pushed the export-D99099930 branch from 9ac5354 to ff39d6a Compare April 8, 2026 09:38
@meta-codesync meta-codesync bot closed this in 77332d2 Apr 8, 2026
@facebook-github-tools facebook-github-tools bot added the Merged This PR has been merged. label Apr 8, 2026
@meta-codesync
Copy link
Copy Markdown

meta-codesync bot commented Apr 8, 2026

This pull request has been merged in 77332d2.

@react-native-bot
Copy link
Copy Markdown
Collaborator

This pull request was successfully merged by @huntie in 77332d2

When will my fix make it into a release? | How to file a pick request?

@huntie huntie deleted the export-D99099930 branch April 8, 2026 10:49
huntie added a commit to huntie/react-native that referenced this pull request Apr 8, 2026
Summary:
Pull Request resolved: facebook#56307

Implement the `Page.captureScreenshot` CDP command in the inspector backend, allowing DevTools to capture an on-demand screenshot of the current app view. This is a minimal implementation supporting only the `format` (jpeg/png/webp) and `quality` (0-100, jpeg only) parameters, returning base64-encoded image data.

The feature is gated behind a new `fuseboxCaptureScreenshotEnabled` React Native feature flag, wired through `InspectorFlags` following the same pattern as frame recording.

**Motivation**

Improve agent verification / user feedback during AI sessions. We've proven that screenshots (in performance traces) are useful for understanding how components render on screen, and exposing this as an on-demand CDP method is relatively cheap today vs the larger task of modelling the DOM (Elements panel).

**Changes**

- New `fuseboxCaptureScreenshotEnabled` feature flag + `InspectorFlags` wiring (C++, Android JNI, Kotlin)
- `HostTargetDelegate::captureScreenshot()` virtual method with async callback
- C++ CDP handler in `HostAgent` — parses `format`/`quality`, delegates to platform, sends async CDP response (gated by flag)
- iOS (`RCTHost.mm`): Captures key window via `UIGraphicsImageRenderer` + `drawViewHierarchyInRect`, encodes to PNG/JPEG
- Android (`ReactHostImpl.kt`): Captures decor view via `Bitmap` + `Canvas` + `View.draw()`, encodes to PNG/JPEG/WebP
- 4 C++ tests: success, failure, param forwarding, flag-disabled rejection

Changelog: [Internal]

Reviewed By: hoxyq

Differential Revision: D99099930

fbshipit-source-id: d4d2ef86ba20d2ee230903e152dd21e11f29cbb8
huntie added a commit to huntie/react-native that referenced this pull request Apr 8, 2026
Summary:
Pull Request resolved: facebook#56307

Implement the `Page.captureScreenshot` CDP command in the inspector backend, allowing DevTools to capture an on-demand screenshot of the current app view. This is a minimal implementation supporting only the `format` (jpeg/png/webp) and `quality` (0-100, jpeg only) parameters, returning base64-encoded image data.

The feature is gated behind a new `fuseboxCaptureScreenshotEnabled` React Native feature flag, wired through `InspectorFlags` following the same pattern as frame recording.

**Motivation**

Improve agent verification / user feedback during AI sessions. We've proven that screenshots (in performance traces) are useful for understanding how components render on screen, and exposing this as an on-demand CDP method is relatively cheap today vs the larger task of modelling the DOM (Elements panel).

**Changes**

- New `fuseboxCaptureScreenshotEnabled` feature flag + `InspectorFlags` wiring (C++, Android JNI, Kotlin)
- `HostTargetDelegate::captureScreenshot()` virtual method with async callback
- C++ CDP handler in `HostAgent` — parses `format`/`quality`, delegates to platform, sends async CDP response (gated by flag)
- iOS (`RCTHost.mm`): Captures key window via `UIGraphicsImageRenderer` + `drawViewHierarchyInRect`, encodes to PNG/JPEG
- Android (`ReactHostImpl.kt`): Captures decor view via `Bitmap` + `Canvas` + `View.draw()`, encodes to PNG/JPEG/WebP
- 4 C++ tests: success, failure, param forwarding, flag-disabled rejection

Changelog: [Internal]

Reviewed By: hoxyq

Differential Revision: D99099930

fbshipit-source-id: d4d2ef86ba20d2ee230903e152dd21e11f29cbb8
huntie pushed a commit to huntie/react-native that referenced this pull request Apr 8, 2026
Backports some CDP Performance features and stability improvements to `0.83-stable`.

This includes:
- Remaining implementation of Frame Timings and screenshot capture in performance traces (Android)
- New support for Frame Timings and screenshot capture on iOS
- Optimisations to trace chunk generation, memory usage during performance recording
- `Page.captureScreenshot` (Android, iOS)

All features remain gated behind feature flags (`fuseboxFrameRecordingEnabled`, `fuseboxScreenshotCaptureEnabled`).

**Commits applied**

- Define TracingCategory enum (facebook#54377) bd6c6bf
- Use TracingCategory in TraceEvent (facebook#54378) ce60f27
- Simple parser for serialized tracing categories (facebook#54379) 62275b6
- Propagate tracing categories to recording state (facebook#54380) 3841ef0
- Re-land "Revert D85999774: [rn][android] Add FrameTiming module" (facebook#54502) 85905ad
- Add screenshot category (facebook#54537) 5d9cb80
- Define HostTargetTracingDelegate (facebook#54622) be0dae0
- Define TracingDelegate for Android Host (facebook#54628) a212e95
- Use new API for tracing state on Android (facebook#54629) 532d0be
- Internalize TracingState interface (facebook#54631) 58ec261
- Move TracingState interfaces to inspector package (facebook#54632) 10d0d99
- Rename values of TracingState enum (facebook#54630) be94707
- FrameTiming module to subscribe to Inspector tracing lifecycle (facebook#54633) 04ee02b
- Clarify HostTracingProfile and HostTraceRecordingState (facebook#54677) ec92f12
- Introduce TimeWindowedBuffer (facebook#54679) d6ee54f
- Keep tracing time window on TraceRecordingState (facebook#54673) e651563
- Define FrameTimingSequence (facebook#54674) 5b7d92f
- Define an endpoint on HostTarget to capture frame timings (facebook#54672) f469aa3
- Extract frame trace events construction logic (facebook#54675) 57973fa
- Define serializers for frame timings as part of HostTargetTracingProfile (facebook#54681) 587d360
- Propagate Frames data through Host (facebook#54671) 26ff069
- Cleanup no longer used jni layer for frame timings (facebook#54678) 9ba4ce6
- Fix screenshot typo (facebook#54742) 52186a3
- Add optional screenshot argument to FrameTimingSequence (facebook#54743) 57c29fc
- Frame screenshot event generation (facebook#54744) b447d26
- Frame screenshots capture implementation (facebook#54745) f3c9a8d
- BeginDrawing: INTENDED_VSYNC_TIMESTAMP -> VSYNC_TIMESTAMP (facebook#54765) 9221772
- Add frames category (facebook#54768) 31a0c9a
- Specify correct category for SetLayerTreeId event (facebook#54769) cd055e9
- Reduce the screenshots size (facebook#54800) e4a5a56
- Remove Commit from FrameTimingSequence (facebook#54779) 39f7703
- Fix potential bitmap leaks in FrameTimingsObserver (facebook#55652) 3918dd1
- Capture initial screenshot when starting frame timing trace (facebook#55720) 863f5c0
- Refactor FrameTimingsObserver for multi-activity support (facebook#55740) 8230f3b
- Reorder FrameTimingsObserver methods (facebook#55743) f56b295
- Increase frame capture quality, apply scaling after DPI normalization (facebook#55731) e5f9f5f
- Fix FrameTimingsObverver to initiate PixelCopy on main thread (facebook#55744) d552f2a
- Fix bitmap reuse race condition in FrameTimingsObserver (facebook#55745) 3924768
- Fix trailing frame capture after recording ended (facebook#55704) 47684ca
- Move base64Encode into react/utils (facebook#55873) 422770d
- Move screenshot Base64 encoding to trace serialization (facebook#55803) dc4c36e
- Restore inspector addPage listener callback (facebook#55925) 8c763fc
- Add tracing helper functions for RNDT traces in C++ and Kotlin (facebook#55935) 4f3f536
- Introduce fuseboxFrameRecordingEnabled flag, gate existing code (facebook#55941) 1aa7a32
- Implement Performance frames and screenshots on iOS (facebook#56015) 64a1a10
- Add pixel diffing to RCTFrameTimingsObserver (facebook#56043) 9d231af
- Add dynamic sampling to frame screenshots (facebook#56048) d309cda
- Switch trace event chunks from event count to size based (facebook#56080) d3b33f5
- Increase trace screenshot scale factor to 1x (facebook#56079) 972a30d
- Add Page.captureScreenshot CDP support (facebook#56307) 77332d2
- Fix data race on PerformanceObserver entry buffer (facebook#56352) 5eb1ca1
- [LOCAL] Remove stale frame event code from PerformanceTracer
- [LOCAL] Update Podfile.lock
huntie pushed a commit to huntie/react-native that referenced this pull request Apr 8, 2026
Backports some CDP Performance features and stability improvements to `0.83-stable`.

This includes:
- Remaining implementation of Frame Timings and screenshot capture in performance traces (Android)
- New support for Frame Timings and screenshot capture on iOS
- Optimisations to trace chunk generation, memory usage during performance recording
- `Page.captureScreenshot` (Android, iOS)

All features remain gated behind feature flags (`fuseboxFrameRecordingEnabled`, `fuseboxScreenshotCaptureEnabled`).

**Commits applied**

- Define TracingCategory enum (facebook#54377) bd6c6bf
- Use TracingCategory in TraceEvent (facebook#54378) ce60f27
- Simple parser for serialized tracing categories (facebook#54379) 62275b6
- Propagate tracing categories to recording state (facebook#54380) 3841ef0
- Re-land "Revert D85999774: [rn][android] Add FrameTiming module" (facebook#54502) 85905ad
- Add screenshot category (facebook#54537) 5d9cb80
- Define HostTargetTracingDelegate (facebook#54622) be0dae0
- Define TracingDelegate for Android Host (facebook#54628) a212e95
- Use new API for tracing state on Android (facebook#54629) 532d0be
- Internalize TracingState interface (facebook#54631) 58ec261
- Move TracingState interfaces to inspector package (facebook#54632) 10d0d99
- Rename values of TracingState enum (facebook#54630) be94707
- FrameTiming module to subscribe to Inspector tracing lifecycle (facebook#54633) 04ee02b
- Clarify HostTracingProfile and HostTraceRecordingState (facebook#54677) ec92f12
- Introduce TimeWindowedBuffer (facebook#54679) d6ee54f
- Keep tracing time window on TraceRecordingState (facebook#54673) e651563
- Define FrameTimingSequence (facebook#54674) 5b7d92f
- Define an endpoint on HostTarget to capture frame timings (facebook#54672) f469aa3
- Extract frame trace events construction logic (facebook#54675) 57973fa
- Define serializers for frame timings as part of HostTargetTracingProfile (facebook#54681) 587d360
- Propagate Frames data through Host (facebook#54671) 26ff069
- Cleanup no longer used jni layer for frame timings (facebook#54678) 9ba4ce6
- Fix screenshot typo (facebook#54742) 52186a3
- Add optional screenshot argument to FrameTimingSequence (facebook#54743) 57c29fc
- Frame screenshot event generation (facebook#54744) b447d26
- Frame screenshots capture implementation (facebook#54745) f3c9a8d
- BeginDrawing: INTENDED_VSYNC_TIMESTAMP -> VSYNC_TIMESTAMP (facebook#54765) 9221772
- Add frames category (facebook#54768) 31a0c9a
- Specify correct category for SetLayerTreeId event (facebook#54769) cd055e9
- Reduce the screenshots size (facebook#54800) e4a5a56
- Remove Commit from FrameTimingSequence (facebook#54779) 39f7703
- Fix potential bitmap leaks in FrameTimingsObserver (facebook#55652) 3918dd1
- Capture initial screenshot when starting frame timing trace (facebook#55720) 863f5c0
- Refactor FrameTimingsObserver for multi-activity support (facebook#55740) 8230f3b
- Reorder FrameTimingsObserver methods (facebook#55743) f56b295
- Increase frame capture quality, apply scaling after DPI normalization (facebook#55731) e5f9f5f
- Fix FrameTimingsObverver to initiate PixelCopy on main thread (facebook#55744) d552f2a
- Fix bitmap reuse race condition in FrameTimingsObserver (facebook#55745) 3924768
- Fix trailing frame capture after recording ended (facebook#55704) 47684ca
- Move base64Encode into react/utils (facebook#55873) 422770d
- Move screenshot Base64 encoding to trace serialization (facebook#55803) dc4c36e
- Restore inspector addPage listener callback (facebook#55925) 8c763fc
- Add tracing helper functions for RNDT traces in C++ and Kotlin (facebook#55935) 4f3f536
- Introduce fuseboxFrameRecordingEnabled flag, gate existing code (facebook#55941) 1aa7a32
- Implement Performance frames and screenshots on iOS (facebook#56015) 64a1a10
- Add pixel diffing to RCTFrameTimingsObserver (facebook#56043) 9d231af
- Add dynamic sampling to frame screenshots (facebook#56048) d309cda
- Switch trace event chunks from event count to size based (facebook#56080) d3b33f5
- Increase trace screenshot scale factor to 1x (facebook#56079) 972a30d
- Add Page.captureScreenshot CDP support (facebook#56307) 77332d2
- Fix data race on PerformanceObserver entry buffer (facebook#56352) 5eb1ca1
- [LOCAL] Remove stale frame event code from PerformanceTracer
- [LOCAL] Update Podfile.lock
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged This PR has been merged. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants